package cn.yanxiaohui.service.web.config;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Date;

/**
 * @author yanxh
 */
@Configuration
@Component
@EnableScheduling
public class BackUpConfig {

    private static Logger logger = LoggerFactory.getLogger(BackUpConfig.class);

    @Value("${spring.datasource.username}")
    private  String username;
    @Value("${spring.datasource.password}")
    private  String password;
    @Value("${backup.source.savePath}")
    private  String savePath;
    @Value("${backup.source.databaseName}")
    private  String databaseName;
    @Value("${backup.source.hostIP}")
    private  String hostIP;
    static final String FORMAT = "yyyy-MM-dd";
    /**
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 每天凌晨2点自动执行数据库备份操作
     */
    @Scheduled(cron = " 0 0 0 * * ?")
    public void backUpDatabase(){
        exportDatabaseTool(hostIP,username,password, savePath,databaseName);
        delAllFile(savePath);
    }


    /**
     * Java代码实现MySQL数据库导出
     *
     * @author GaoHuanjie
     * @param hostIP MySQL数据库所在服务器地址IP
     * @param userName 进入数据库所需要的用户名
     * @param password 进入数据库所需要的密码
     * @param savePath 数据库导出文件保存路径
     * @param databaseName 要导出的数据库名
     * @return 返回true表示导出成功，否则返回false。
     */
    private boolean exportDatabaseTool(String hostIP, String userName, String password, String savePath,
                                             String databaseName) {
        File saveFile = new File(savePath);
        if (!saveFile.exists()) {// 如果目录不存在
            saveFile.mkdirs();// 创建文件夹
        }
        if (!savePath.endsWith(File.separator)) {
            savePath = savePath + File.separator;
        }
        String fileName = DateUtil.format(new Date(), FORMAT)+".sql";
        //拼接命令行的命令
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("mysqldump").append(" --opt").append(" -h").append(hostIP);
        stringBuilder.append(" --user=").append(userName).append(" --password=").append(password)
                .append(" --lock-all-tables=true");
        stringBuilder.append(" --result-file=").append(savePath + fileName).append(" --default-character-set=utf8 ")
                .append(databaseName);
        logger.info(stringBuilder.toString());
        try {
            String[] commands = {  "/bin/sh", "-c", stringBuilder.toString()};
            Runtime runtime = Runtime.getRuntime();
            Process process = runtime.exec(commands);
            logger.info("process.waitFor:"+process.waitFor());
            if (process.waitFor() == 0) {// 0 表示线程正常终止。
                logger.info("数据库备份成功^_^");
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private void delAllFile(String savePath){
        File file = new File(savePath);
        if (!file.exists()) {
            System.out.println("文件路径不存在");
            return;
        }
        if (!file.isDirectory()) {
            System.out.println("文件路径非文件目录");
            return;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            String fileName = tempList[i];
            try {
                String substring = fileName.substring(0, fileName.lastIndexOf("."));
                Date date = DateUtil.parse(substring, FORMAT);
                // 保留最近七天的数据
                if(System.currentTimeMillis() - date.getTime() <= 7 * 24 * 60 * 60 * 1000){
                    continue;
                }
            }catch (Exception e){
                System.out.println("非日期格式文件，直接删除");
            }
            if (savePath.endsWith(File.separator)) {
                temp = new File(savePath + fileName);
            } else {
                temp = new File(savePath + File.separator + fileName);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(savePath + "/" + fileName);// 先删除文件夹里面的文件
                delFolder(savePath + "/" + fileName);// 再删除空文件夹
            }
        }
    }

    /***
     * 删除文件夹
     */
    private void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            java.io.File myFilePath = new java.io.File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * Linux下 Runtime.getRuntime().exec(new String[]{"/bin/sh","-c"});
     * Windows下 Runtime.getRuntime().exec(new String[]{"cmd","/c",cmds});
     */
    public static void main(String[] args){
        InputStream in = null;
        String result = null;

        //拼接命令行的命令
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("mysqldump").append(" --opt").append(" -h").append("123.207.148.250");
        stringBuilder.append(" --user=").append("root").append(" --password=").append("yanxiaohui")
                .append(" --lock-all-tables=true");
        stringBuilder.append(" --result-file=").append("/project/database/20190925.sql").append(" --default-character-set=utf8 ")
                .append("yxh_dev");
        try {

            //调用外部执行exe文件的javaAPI
            String[] commands = {"/bin/sh", "-c", stringBuilder.toString()};
            Process process = Runtime.getRuntime().exec(commands);
            process.waitFor();
            in = process.getInputStream();
            BufferedReader read = new BufferedReader(new InputStreamReader(in));
            while((result = read.readLine())!=null) {
                System.out.println(result);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}